Skip to content

feat(currency): Migrate CurrencyFormatter to adopt the new design with generic ValueRepresentation (Decimal) and add short/narrow constructors#8145

Merged
younies merged 1 commit into
unicode-org:mainfrom
younies:currency-short-narrow-decimal
Jul 6, 2026
Merged

Conversation

@younies

@younies younies commented Jun 26, 2026

Copy link
Copy Markdown
Member

Migrate the currency formatter based on the design doc:
https://hackmd.io/@younies/number_formatter_4x

Overview

This PR refactors the CurrencyFormatter in icu_experimental to align with the proposed design for modular, zero-copy currency formatting (Option 1 in the design doc).

Specifically, it introduces the ValueRepresentation typestate pattern to partition constructors by capability and representation, starting with the standard Decimal representation, while ensuring consistent locale and numbering system resolution across both short and narrow widths.

Changelog

  • Implement ValueRepresentation trait and Decimal marker struct to support typestate-based currency formatting.
  • Refactor CurrencyFormatter to be generic over ValueRepresentation: pub struct CurrencyFormatter<V: ValueRepresentation>.
  • Migrate the old short and narrow currency formatter to CurrencyFormatter<Decimal> with new try_new_short and try_new_narrow constructors (and their unstable/buffer variants), removing the old non-generic try_new constructors.
  • Fix Narrow Fallback: Update both compiled and unstable versions of try_new_narrow to use robust fallback loading, ensuring they correctly support numbering system overrides consistently with try_new_short.
  • Update experimental currency tests and doctests to use the new generic API, including comprehensive test cases for narrow formatting and numbering system overrides.

TAG=agy
CONV=0f8e0e91-077a-4704-b63f-0c02f37cbc41

@younies younies changed the title Refactor CurrencyFormatter to be generic over ValueRepresentation Migrate CurrencyFormatter to generic ValueRepresentation (Decimal) Jun 26, 2026
@younies younies force-pushed the currency-short-narrow-decimal branch 4 times, most recently from 0e87de5 to b35fab7 Compare June 26, 2026 14:22
@younies younies changed the title Migrate CurrencyFormatter to generic ValueRepresentation (Decimal) currency: Migrate CurrencyFormatter to generic ValueRepresentation (Decimal) and add short/narrow constructors Jun 26, 2026
@younies younies changed the title currency: Migrate CurrencyFormatter to generic ValueRepresentation (Decimal) and add short/narrow constructors currency: Migrate CurrencyFormatter to adopt the new design with generic ValueRepresentation (Decimal) and add short/narrow constructors Jun 26, 2026
@younies younies requested a review from robertbastian June 26, 2026 14:26
Comment thread components/experimental/src/dimension/currency/format.rs Outdated
Comment thread components/experimental/src/dimension/currency/formatter.rs
Comment thread components/experimental/src/dimension/currency/format.rs Outdated
try_new: skip,
try_new_with_buffer_provider,
try_new_unstable,
try_new_narrow: skip,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use the macro-generated version?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! We have refactored the constructors to use the macro-generated versions as much as possible (for the buffer and unstable constructors).

However, we still have to skip the compiled constructors (try_new_short/try_new_narrow) in the macro and implement them manually. This is because CurrencyFormatter is a composite formatter that internally instantiates DecimalFormatter (from icu_decimal). Since icu_experimental's local compiled data provider (Baked) only contains experimental keys and does not implement the stable decimal keys, the macro-generated compiled constructors fail to compile due to unsatisfied trait bounds on Baked.

Manually implementing them allows us to initialize DecimalFormatter using its own compiled data, while loading the currency-specific data from icu_experimental's Baked provider. This is the same established pattern used in RelativeTimeFormatter (see relativetime.rs:178).

We have added a TODO comment in the code to re-evaluate and try to use the macro-generated compiled versions once CurrencyFormatter is stabilized and migrated out of experimental.

Additionally, while refactoring, we noticed that try_new_narrow was missing the numbering system fallback loading logic that try_new_short had. We have updated both the compiled and unstable versions of narrow to use the fallback loader, so they are now fully consistent and correct.

@younies

younies commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

We have updated this PR to refactor the CurrencyFormatter design:

  • The constructors (try_new_short, try_new_narrow, and their unstable/buffer variants) now take currency_code: &CurrencyCode as input.
  • The CurrencyFormatter struct now stores this as bound_currency.
  • The format_fixed_decimal method signature has been simplified to remove the currency_code parameter, as it now uses the bound_currency stored in the struct.

This aligns the Short/Narrow formatter API with the Long formatter design (in the stacked PR #8150), ensuring a consistent API across all widths.

@younies younies force-pushed the currency-short-narrow-decimal branch from 13d73f5 to 8a68189 Compare June 29, 2026 12:15
@younies

younies commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

@robertbastian : Ping

@younies younies force-pushed the currency-short-narrow-decimal branch from 8a68189 to 8e24118 Compare July 2, 2026 11:14
@younies younies requested review from Manishearth and sffc as code owners July 2, 2026 11:14
@younies younies force-pushed the currency-short-narrow-decimal branch from 8e24118 to 5ffcd74 Compare July 2, 2026 11:14
@Manishearth Manishearth removed their request for review July 2, 2026 12:41
@younies younies changed the title currency: Migrate CurrencyFormatter to adopt the new design with generic ValueRepresentation (Decimal) and add short/narrow constructors feat(currency): Migrate CurrencyFormatter to adopt the new design with generic ValueRepresentation (Decimal) and add short/narrow constructors Jul 2, 2026
@younies younies removed the request for review from sffc July 2, 2026 18:13
@younies younies force-pushed the currency-short-narrow-decimal branch 2 times, most recently from e9b611c to 7bea1e7 Compare July 5, 2026 09:15
…h generic ValueRepresentation (Decimal) and add short/narrow constructors (unicode-org#8145)
@younies younies force-pushed the currency-short-narrow-decimal branch from 7bea1e7 to 3fa1d3d Compare July 5, 2026 10:14
@younies younies merged commit 0730ac9 into unicode-org:main Jul 6, 2026
34 checks passed
@younies younies deleted the currency-short-narrow-decimal branch July 6, 2026 15:01
robertbastian pushed a commit that referenced this pull request Jul 7, 2026
)

This PR migrates the `LongCurrencyFormatter` functionality into the main
`CurrencyFormatter`, building on top of the refactoring in #8145.

## Changelog
- Migrated `LongCurrencyFormatter` to `CurrencyFormatter`.
- Added `try_new_long` and `try_new_long_unstable` constructors.
- Added tests for long currency formatting, including numbering system
overrides.
- Removed redundant `long_formatter.rs` and `long_format.rs` files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants